home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
os2
/
daytime.zip
/
daytimed.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-16
|
8KB
|
319 lines
/* daytimed.c - daytime and time server daemon
*
* for IBM TCP/IP 2.0 for OS/2
*
* Author: Kai Uwe Rommel <rommel@ars.muc.de>
* Created: Sun Apr 10 1994
*
* This code is in the public domain.
* Let the author know if you make improvements or fixes, though.
*/
static char *rcsid =
"$Id: daytimed.c,v 1.3 1995/08/20 08:15:10 rommel Exp rommel $";
static char *rcsrev = "$Revision: 1.3 $";
/*
* $Log: daytimed.c,v $
* Revision 1.3 1995/08/20 08:15:10 rommel
* updated for new emx socket library, IBM compiler
* fixed minor bugs
*
* Revision 1.2 1994/07/17 21:06:45 rommel
* bug fix: display correct peer address
*
* Revision 1.1 1994/07/17 20:46:11 rommel
* Initial revision
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <time.h>
#include <string.h>
#ifdef OS2
#ifdef __IBMC__
#define BSD_SELECT
#include <types.h>
#include <sys/select.h>
#endif
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef __EMX__
#define psock_errno perror
#define soclose close
#define sock_init() 0
#endif
#endif
typedef enum {TIME = 0, DAYTIME = 1} service;
typedef enum {UDP = 0, TCP = 1} protocol;
void send_time(int socket, service serv, protocol proto)
{
struct sockaddr_in client;
struct linger linger;
char buffer[64], *timestr;
time_t now;
int bytes, size;
time(&now);
if (serv == DAYTIME)
{
timestr = ctime(&now);
bytes = strlen(timestr) + 1;
}
else
{
/*
* The time service returns seconds since 1900/01/01 00:00:00 GMT, not
* since 1970 as assumed by Unix time_t values. We need to add 70
* years' worth of seconds. Fortunately, RFC 868 tells us that the
* daytime value 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT.
*/
now += 2208988800UL;
now = htonl(now);
timestr = (char *) &now;
bytes = sizeof(now);
}
if (proto == TCP)
{
linger.l_onoff = 1;
linger.l_linger = 10;
if (setsockopt(socket, SOL_SOCKET, SO_LINGER,
(char *) &linger, sizeof(linger)) < 0)
psock_errno("setsockopt(SO_LINGER)");
else
if (send(socket, timestr, bytes, 0) < 0)
psock_errno("send()");
size = sizeof(client);
if (getpeername(socket, (struct sockaddr *) &client, &size) < 0)
psock_errno("getsockname()");
soclose(socket);
}
else
{
size = sizeof(client);
if (recvfrom(socket, buffer, sizeof(buffer), 0,
(struct sockaddr *) &client, &size) < 0)
psock_errno("recvfrom()");
else
if (sendto(socket, timestr, bytes, 0,
(struct sockaddr *) &client, size) < 0)
psock_errno("sendto()");
}
printf("served '%s' request from %s via '%s'\n",
serv == DAYTIME ? "daytime" : "time",
inet_ntoa(client.sin_addr),
proto == TCP ? "tcp" : "udp");
}
int serve(void)
{
struct sockaddr_in server, client;
struct servent *port;
int tcp_13, tcp_37, udp_13, udp_37, sock_client, length;
service serv;
protocol proto;
/* set up daytime (tcp) server */
if ((tcp_13 = socket(PF_INET, SOCK_STREAM, 0)) < 0)
return psock_errno("socket(daytime tcp)"), 1;
if ((port = getservbyname("daytime", "tcp")) == NULL)
return psock_errno("getservbyname(daytime tcp)"), 1;
server.sin_family = AF_INET;
server.sin_port = port -> s_port;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(tcp_13, (struct sockaddr *) &server, sizeof(server)) < 0)
return psock_errno("bind(daytime tcp)"), 1;
if (listen(tcp_13, 4) != 0)
return psock_errno("listen(daytime tcp)"), 1;
/* set up daytime (udp) server */
if ((udp_13 = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
return psock_errno("socket(daytime udp)"), 1;
if ((port = getservbyname("daytime", "udp")) == NULL)
return psock_errno("getservbyname(daytime udp)"), 1;
server.sin_family = AF_INET;
server.sin_port = port -> s_port;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(udp_13, (struct sockaddr *) &server, sizeof(server)) < 0)
return psock_errno("bind(daytime udp)"), 1;
/* set up time (tcp) server */
if ((tcp_37 = socket(PF_INET, SOCK_STREAM, 0)) < 0)
return psock_errno("socket(time tcp)"), 1;
if ((port = getservbyname("time", "tcp")) == NULL)
return psock_errno("getservbyname(time tcp)"), 1;
server.sin_family = AF_INET;
server.sin_port = port -> s_port;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(tcp_37, (struct sockaddr *) &server, sizeof(server)) < 0)
return psock_errno("bind(time tcp)"), 1;
if (listen(tcp_37, 4) != 0)
return psock_errno("listen(time tcp)"), 1;
/* set up time (udp) server */
if ((udp_37 = socket(PF_INET, SOCK_DGRAM, 0)) < 0)
return psock_errno("socket(time udp)"), 1;
if ((port = getservbyname("time", "udp")) == NULL)
return psock_errno("getservbyname(time udp)"), 1;
server.sin_family = AF_INET;
server.sin_port = port -> s_port;
server.sin_addr.s_addr = INADDR_ANY;
if (bind(udp_37, (struct sockaddr *) &server, sizeof(server)) < 0)
return psock_errno("bind(time udp)"), 1;
/* server loop */
for (;;)
{
struct timeval tv;
fd_set fds;
int rc, socket;
/* wait for a request */
FD_ZERO(&fds);
FD_SET(tcp_13, &fds);
FD_SET(tcp_37, &fds);
FD_SET(udp_13, &fds);
FD_SET(udp_37, &fds);
tv.tv_sec = 60;
tv.tv_usec = 0;
if ((rc = select(FD_SETSIZE, &fds, 0, 0, &tv)) < 0)
return psock_errno("select()"), 1;
else if (rc == 0)
continue;
/* determine type and protocol */
if (FD_ISSET(tcp_13, &fds) != 0)
{
socket = tcp_13;
serv = DAYTIME;
proto = TCP;
}
else if (FD_ISSET(tcp_37, &fds) != 0)
{
socket = tcp_37;
serv = TIME;
proto = TCP;
}
else if (FD_ISSET(udp_13, &fds) != 0)
{
socket = udp_13;
serv = DAYTIME;
proto = UDP;
}
else if (FD_ISSET(udp_37, &fds) != 0)
{
socket = udp_37;
serv = TIME;
proto = UDP;
}
else
continue;
/* and handle it */
if (proto == TCP)
{
length = sizeof(client);
if ((sock_client = accept(socket,
(struct sockaddr *) &client, &length)) == -1)
return psock_errno("accept()"), 1;
send_time(sock_client, serv, TCP);
}
else
send_time(socket, serv, UDP);
}
return 0;
}
int usage(void)
{
printf("\nUsage: daytimed [[-dtTU] socket]\n"
"\n -d serve daytime request on socket"
"\n -t serve time request on socket"
"\n -T serve 'tcp' request"
"\n -U serve 'udp' request\n"
"\nThese options are for use with inetd, the default is to run as a daemon\n");
return 1;
}
int main(int argc, char **argv)
{
int opt;
service serv = TIME;
protocol proto = TCP;
tzset();
if (sock_init())
return psock_errno("sock_init()"), 1;
if (argc == 1)
return serve();
while ((opt = getopt(argc, argv, "?TUdt")) != EOF)
switch (opt)
{
case 'd':
serv = DAYTIME;
break;
case 't':
serv = TIME;
break;
case 'T':
proto = TCP;
break;
case 'U':
proto = UDP;
break;
default:
return usage();
}
if (optind == argc)
return usage();
send_time(atoi(argv[optind]), serv, proto);
return 0;
}
/* end of daytimed.c */